from typing import List, Dict, Optional
from sqlalchemy import and_, distinct

from app.tools_apollo.models import ApolloNamespace, ApolloItem
from sqlalchemy.orm import Session


def apollo_search(db: Session, page: int, per_page: int, app_name: Optional[str] = None,
                  key: Optional[str] = None, value: Optional[str] = None) -> List[Dict]:
    sql = db.query(ApolloNamespace). \
        outerjoin(ApolloItem, ApolloNamespace.Id == ApolloItem.NamespaceId). \
        with_entities(ApolloNamespace.AppId.label('app_name'),
                      ApolloNamespace.ClusterName.label('cluster_name'),
                      ApolloItem.Key.label('key'),
                      ApolloItem.Value.label('value'),
                      ApolloItem.DataChange_CreatedTime.label('created_time'),
                      ApolloItem.DataChange_LastTime.label('last_time'))

    if app_name != 'all':
        sql = sql.filter(ApolloNamespace.AppId == app_name)

    if value:
        return sql.filter(
            and_(ApolloNamespace.IsDeleted == 0, ApolloItem.IsDeleted == 0, ApolloItem.Key != '',
                 ApolloItem.Value.like(f"%{value}%"))).order_by("app_name").paginate(page=page, per_page=per_page)

    return sql.filter(
        and_(ApolloNamespace.IsDeleted == 0, ApolloItem.IsDeleted == 0, ApolloItem.Key.like(f"%{key}%"),
             ApolloItem.Value.like(f"%{value}%"))).order_by("app_name").paginate(page=page, per_page=per_page)


def apollo_app_name(db: Session) -> List[Dict]:
    return db.query(ApolloNamespace).with_entities(distinct(ApolloNamespace.AppId).label("app_name")).to_dict()
